#pragma once
#ifndef __STATUS__H__
#define __STATUS__H__

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include "../lib/Word.h"
#include "../lib/Syntax.h"
#include "FollowWord.h"
#include "../table/GotoTable.h"
#include "../table/ActionTable.h"
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::pair;
using std::map;
using std::set;

// 状态转换集
namespace compile
{
	class Status
	{
	public:
		Status();
		Status(Syntax* s, FollowWord* follow);
		~Status();
		void printStatusSet();
		void print();
		ActionTable getActionTable() const;
		GotoTable getGotoTable() const;
		vector<pair<string, string>> getStartStatus() const;

	private:
		string read_mark; // 走点标记
		vector< vector< pair<string, string> > >status_set; // 状态集合
		ActionTable action_table; // 状态动作表
		GotoTable goto_table; // 状态转移表

		
		void calculateStatusSet(vector<Word> syntax, string enter);
		void insertReducedData(map<string, set<string>>follow);


		int checkSet(vector <pair<string, string>> status_vector);
		
		vector<pair<string, string>>initPairVector(vector<Word>syntax, 
			string enter) const;
		
		static string polyfillChar(char new_char);
		
		static bool ifEndSign(char sign);
		
		string moveReadMark(string content) const;

		vector<pair<string, int>> getNextSignSet(
			vector<pair<string, string>> this_status) const;

		vector< pair<string, string> > getNewVector(
			vector<pair<string, string>>this_status,
			string sign, unsigned int start, unsigned int end, 
			vector<Word>* syntax) const;

		static vector<pair <string, string>> concatVector(
			vector<pair<string, string>> result,
			vector<pair<string, string>>new_vector);

		vector<pair<string, string>> recureGetNewWord(
			vector<pair<string, string>> result, 
			vector<Word>* syntax,
			set<string>* if_visited) const;

		vector<pair<string, string>>getWord(string key, 
			vector<Word>* syntax, 
			set<string>* if_visited) const;

		string initReadMark(string content) const;

		void insertDataInTable(string status_num, 
			string status_sign, int change_num);

		static string changeInt(int change_num);

		string deleteReadMark(string str) const;

		unsigned int getIndexInStartStatus(string key, string content) const;
	};
}
#endif